package api;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import api.error.InvalidRequestException;
import api.error.UnknownResponseException;
import application.Launcher;
import application.XMLUtil;

public class AdeptInterpreter extends Interpreter{
	
	private Command[] commands = new Command[]{
			new Command("exit", new String[]{}, "Exits the operator program on the Adept Controller"),
			new Command("mon", new String[]{"text"}, "Sends a message to the Adept Monitor")
	};
	private static HashMap<Integer, String> codes = loadResponseCodes();
	public static String getText(int code)
	{
		return codes.get(new Integer(code));
	}
	private static HashMap<Integer, String> loadResponseCodes()
	{
		HashMap<Integer,String> codes = new HashMap<Integer, String>();
		String uri = Launcher.root + "/lib/codes.xml";
		Document content = XMLUtil.getDocument(new File(uri));
		NodeList list = content.getElementsByTagName("code");
		
		for(int i = 0; i < list.getLength(); i++)
		{
			Element elem = (Element)list.item(i);
			String code = elem.getAttribute("digit");
			String value = elem.getAttribute("text");
			
			codes.put(Integer.parseInt(code), value);
			System.out.println("Added code: " + code + " ---> " + value);
		}
		return codes;
	}
	
	public Command[] getCommands() {
		return commands;
	}
	public String[] getStartupCommands()
	{
		return new String[]{"ready"};
	}
	public String[] getReleaseCommands()
	{
		return new String[]{"ready", "exit"};
	}
	
	public List<String> interpretRequest(String command)
			throws InvalidRequestException {
		
		if(command == null || command.trim().length() == 0)
		{
			throw new InvalidRequestException("", "No request was given");
		}
		
		String[] commander = command.split("[ (]");
		String name = commander[0];
		Command it = getCommand(name);
		
		List<String> results = new ArrayList<String>();
		results.add(name);
		if(it == null || it.getParams().length > 0)
		{
			int start = command.indexOf("(");
			int end = command.indexOf(")");
			if((start > 0 && end < 0) || (end > 0 && start < 0) || (start > end))
			{
				if(start < 0)
					throw new InvalidRequestException(command, "Missing '(' in parameter list");
				if(end < 0)
					throw new InvalidRequestException(command, "Missing ')' in parameter list");
			}
			if(start >= 0 && end >= 0)
			{
				String paramSt = command.substring(start+1, end);
				String[] params = paramSt.split(",");
				if(it != null && params.length != it.getParams().length)
					throw new InvalidRequestException(command, "Incorrect number of parameters. Given " + params.length + ", expected " + it.getParams().length);
				for(String s : params)
				{
					if(s.trim().length() > 0)
						results.add(s);
				}
			}
		}
		else
		{
			int start = command.indexOf("(");
			int end = command.indexOf(")");
			if(end > start + 1)
			{
				String paramSt = command.substring(start + 1, end).trim();
				if(paramSt.length() > 0)
					throw new InvalidRequestException(command, "No parameters should be given");
			}
		}
		
		return results;
	}
	
	public List<String> interpretResponse(String response){

		List<String> ret = new ArrayList<String>();
		String[] responses = response.replace("\r", "").split("\n");
		for(String s : responses)
		{
			try{
				int i = Integer.parseInt(s);
				String st = getText(i);
				if(st == null)
					ret.add(s);
				else
					ret.add(st);
			}catch(Exception e){
				ret.add(s);
			}
		}
		
		return ret;
	}
	
	public String toString()
	{
		return "Adept";
	}
	@Override
	public boolean isResponseGood(String response) {
		String[] responses = response.replace("\r", "").split("\n");
		for(String s : responses)
		{
			try{
				int i = Integer.parseInt(s);
				if(i >= 300)
				return false;
			}catch(Exception e){}
		}
		return true;
	}
}
